% setDeadline 20 100 schedule pid 0 for 20% of 100ms --> 0 policy DL_ONLY-->0 policy DL_ANY-->0 policy DL_RELEASE-->0On a uniprocessor, a request for much more than 20% of the CPU is rejected. On a multiprocessor, a request for 98% or 99% is generally successful.
Example A-8 : Helper Functions for Using schedctl()
/* || Issue the schedctl(2) calls to set up deadline scheduling, using || the simpler interface of npri(1). That is, where schedctl() requires || you to set up a structure containing two intervals in nanoseconds, || setDeadlinePct() lets you specify an interval in milliseconds and a || percentage duty cycle. || || As a bonus, setDeadlinePolicy() is a short way to call for any of || the four policies, DL_ONLY, DL_ANY, DL_RELEASE (the rest of the period) || and DL_BLOCK (for the rest of the period). */ #include <errno.h> #include <sys/schedctl.h> #include <stdio.h> /* for stderr, perror */ /* || This local function does the arithmetic to convert a count of || milliseconds into the fields of a timestruc_t. */ static void putMSinTimestruc(timestruc_t *ts, const int milliseconds) { int ms = milliseconds; if (1000 > ms) ts->tv_sec = 0; else { /* set the seconds as well as the nanoseconds */ ts->tv_sec = ms/1000; ms %= 1000; } /* set the nanoseconds: 1e3*1e6 == 1e9 */ ts->tv_nsec = ms*1000000; } /* || Request deadline scheduling for the specified PID (0 for "self"), || in terms of a period in milliseconds and a percentage. */ int setDeadlinePct(int pid, int period, int pct) { struct sched_deadline dd = {{0,0},{0,0}}; int retval; putMSinTimestruc(&dd.dl_period, period); putMSinTimestruc(&dd.dl_alloc, (period * pct)/100); if (-1 == (retval = schedctl(DEADLINE, pid, &dd)) ) { if (ENOSPC == errno) { /* system cannot guarantee that duty cycle */ fprintf(stderr,"schedctl: cannot promise %d%% of %dms\n", pct, period); } else perror("schedctl"); } return retval; } /* || Request one of the constants defined in schedctl.h as a new || scheduling policy for the specified PID. || || Note: the constants DL_ONLY, etc., are declared in schedctl.h || as type-casts to (struct sched_deadline *). That is why this || function speficies that type for its second argument -- when || it logically should be simply "int." */ int setDeadlinePolicy(int pid, struct sched_deadline * policy) { int retval = schedctl(DEADLINE,pid,policy); if (-1 == retval) { char msg[64]; sprintf(msg,"schedctl(DEADLINE,%d,%ld)",pid,policy); perror(msg); } return retval; } #ifdef UNIT_TEST int main(int argc, char **argv) { int pct = 25; int per = 100; int pid = 0; /* which means "self" to schedctl() */ if (1 < argc) { pct = atoi(argv[1]); } if (2 < argc) { per = atoi(argv[2]); } if (3 < argc) { pid = atoi(argv[3]); } if ( (4 < argc) || (0==pct) || (0==per) ) { fprintf(stderr, "usage: setDeadline [ pct_duty_cycle [ period_ms [ pid ] ] ]\n"); exit(); } printf("schedule pid %d for %d%% of %dms --> %d\n", pid, pct, per, setDeadlinePct( pid, per, pct)); printf("policy DL_ONLY-->%d\n", setDeadlinePolicy(pid,DL_ONLY)); printf("policy DL_ANY-->%d\n", setDeadlinePolicy(pid,DL_ANY)); printf("policy DL_RELEASE-->%d\n", setDeadlinePolicy(pid,DL_RELEASE)); } #endif